﻿using System.IO.Ports;
using System.Windows.Documents;
using Serilog;

namespace ZDriver;

public class SerialPort_Driver
{
    // 串口handle
    private SerialPort? _serialPort;

    // 锁对象,确保接收数据线程安全
    // private readonly object _lock = new object();
    
    // 定义数据接收事件
    public event EventHandler<byte[]>? DataReceived;

    /// <summary>
    /// 串口驱动实例
    /// </summary>
    public SerialPort_Driver()
    {
    }

    /// <summary>
    /// 获得当前所有的串口名称
    /// </summary>
    public static string[] GetPortNames()
    {
        return SerialPort.GetPortNames();
    }

    /// <summary>
    /// 是否打开串口
    /// </summary>
    /// <returns>true表示已经打开,false则没有</returns>
    public bool IsOpen()
    {
        return _serialPort != null && _serialPort.IsOpen;
    }

    /// <summary>
    /// 打开串口,如果已经打开则先关闭,再打开
    /// </summary>
    /// <param name="portName">串口名字</param>
    /// <param name="baudRate">波特率</param>
    /// <param name="parity">校验</param>
    /// <param name="dataBits">数据位</param>
    /// <param name="stopBits">停止位</param>
    public void Open(string portName, int baudRate = 115200, Parity parity = Parity.None,
        int dataBits = 8, StopBits stopBits = StopBits.One)
    {
        // 当打开时,关闭串口
        if (_serialPort is {IsOpen: true})
        {
            _serialPort.Close();
        }

        // 重新配置串口参数并打开
        _serialPort = new SerialPort
        {
            PortName = portName,
            BaudRate = baudRate,
            DataBits = dataBits,
            StopBits = stopBits,
            Parity = parity
        };

        // 注册数据接收事件
        _serialPort.DataReceived += (sender, args) =>
        {
            // 打印线程id
            // Console.WriteLine($"DataReceived Thread ID: {Environment.CurrentManagedThreadId}");
            // lock (_lock)
            // {
            // 处理接收到的数据
            if (sender is SerialPort serialPort)
            {
                byte[] buffer = new byte[serialPort.BytesToRead];
                int bytesRead = serialPort.Read(buffer, 0, buffer.Length);
                OnDataReceived(buffer);
            }
            // }
        };
        _serialPort.Open();
    }
    
    /// <summary>
    /// 关闭串口
    /// </summary>
    public void Close()
    {
        _serialPort?.Close();
    }

    /// <summary>
    /// 写入数据到串口
    /// </summary>
    /// <param name="data">待写入数据</param>
    public void Write(byte[] data)
    {
        if (_serialPort == null || !_serialPort.IsOpen)
        {
            Log.Warning("串口未打开,无法发送数据");
            return;
        }

        _serialPort.Write(data, 0, data.Length);
    }

    private void OnDataReceived(byte[] data)
    {
        DataReceived?.Invoke(this, data);
    }
}